

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package convertirafndafd;

import java.util.ArrayList;
import java.util.TreeSet;

/**
 *
 * @author Lisseth
 */
public class ConvertirAFD {
    private ArrayList<String> estados;
    private ArrayList<String> alfabeto;
    private ArrayList<String> nodosFinales;
    private String nodoInicial;
    private ArrayList<String> tabla [][];
 

    public ConvertirAFD(ArrayList<String> estados, ArrayList<String> alfabeto, ArrayList<String> nodosFinales, String nodoInicial, ArrayList<String>[][] t) {

        this.estados = estados;
        this.alfabeto = alfabeto;
        this.nodoInicial = nodoInicial;
        this.nodosFinales = nodosFinales;
        this.tabla = t;


    }
   //Automata finito determinista
      private  ArrayList <String> alfabetoAFD=new ArrayList<String>();
      private  ArrayList <String> estadosAFD=new ArrayList<String>();
      private   char nombreestadoAFD='a';
      private  ArrayList<ArrayList> todosSuBconjuntosAFD= new ArrayList<ArrayList>();
      private String tablaAFD [][];
      private ArrayList<String> nodoFinalesAFD;

   public void crearPrimerSunconjuntoEpsilon(){
        int x=0;//para rrecorrer los subconjuntos
            for(int z=0;z<alfabeto.size();z++){
                    if(alfabeto.get(z).equals("epsilon")){//para saber si en epsilon tiene caracteres //empity si esta vacio
                           TreeSet <String> subconjunto=new TreeSet<String>();
                            subconjunto.add(estados.get(x));
                            
                            if(tabla [x][z].size()!=0){
                                subconjunto.addAll(tabla [x][z]);
                            }
                                ArrayList <String> conjunto=new ArrayList<String>();
                                conjunto.addAll(subconjunto);                           
                                    estadosAFD.add(String.valueOf(nombreestadoAFD));
                                    nombreestadoAFD++;
                                    alfabetoAFD.addAll(alfabeto);
                                    alfabetoAFD.remove("epsilon");


                            todosSuBconjuntosAFD.add(conjunto);
                            todosSuBconjuntosAFD_Repetidos.add(conjunto);
                            System.out.println("con epsilon"+conjunto);
                            subconjuntosAlfabeto(conjunto);
                            int combinaciones=1;
                            while (combinaciones<todosSuBconjuntosAFD.size()) {

                                  
                                       try {
                                            subconjuntosAlfabeto(todosSuBconjuntosAFD.get(combinaciones));
                                            combinaciones++;
                                       } catch (Exception e) {

                                           System.out.println(e);
                                       }
                            }
                            System.out.println(todosSuBconjuntosAFD.size());
                            System.out.println(todosSuBconjuntosAFD_Repetidos.size());
                            System.out.println(estadosAFD.size());
                             for(int s=0;s<estadosAFD.size();s++){
                                   System.out.println(estadosAFD.get(s));
                             }
                             tablaAFND();
String texto ="";
for(int H=0;H<estadosAFD.size();H++){
for(int y=0;y<alfabetoAFD.size();y++){
 System.out.println(texto+="\t"+tablaAFD[x][y]);
            }texto+="\n"; }

                             new TablaAutomataFinitoDeterminista(null, true,estadosAFD,alfabetoAFD,tablaAFD,nodoInicial, nodosFinales()).setVisible(true);
                    }
            }
         }
   //formar subconjuntos con todas las letras del alfabeto del AFND
   public void subconjuntosAlfabeto(ArrayList <String> subconjunto){

       int y=0;//para formar los subconjuntos con todos las letras del alfabeto
       while (y<(alfabeto.size()-1)) {
            crearSunconjuntos(subconjunto,y);
            y++;
       }

   }
   //sunconjuntoCon Epsilon
   public void crearSunconjuntos(ArrayList <String> subconjunto, int alf){//el que voy hacer el reccorrido
     TreeSet conjunto=new TreeSet();// en donde voy ha guardar los elementos
     int x=0;
      while(x<subconjunto.size()){

         for(int z=0;z<estados.size();z++){
           if(estados.get(z).equals(subconjunto.get(x))){
               conjunto.addAll(tabla[z][alf]);
               conjunto.remove("");
                x++;
                    break;
           }

          }
      }

     conjunto.addAll(epsilon(conjunto));//concateno lo que me retorna epsilon
     System.out.println("con epsilon"+conjunto);
     sunbconjuntoRepetidoAFND(conjunto);
     
}
// obtiene el conjunto de epsilon de un conjunto
   public TreeSet<String> epsilon(TreeSet<String> cadenaArrecorrerEpsilon){
        TreeSet conjunto=new TreeSet();//conjunto donde se guarda con epsilon
        ArrayList<String> cadenaRrecorrer=new ArrayList<String>();
        cadenaRrecorrer.addAll(cadenaArrecorrerEpsilon);//conjunto a rrecorrer
 
        int a=0;//para rrecorrer el conjunto
        while(a<cadenaRrecorrer.size()){

         for(int z=0;z<estados.size();z++){
           if(estados.get(z).equals(cadenaRrecorrer.get(a))){
               conjunto.addAll(tabla[z][(alfabeto.size()-1)]);
               conjunto.remove("");
                a++;
                    break;
           }

          }
      }
   return conjunto;
   }
   //compara si no hay conjuntos repetidos
    private  ArrayList<ArrayList> todosSuBconjuntosAFD_Repetidos= new ArrayList<ArrayList>();
   public void   sunbconjuntoRepetidoAFND(TreeSet<String> conjunto){
       ArrayList conj=new ArrayList();
       conj.addAll(conjunto);
       todosSuBconjuntosAFD_Repetidos.add(conj);
            if(!todosSuBconjuntosAFD.contains(conj)){// si esta repetido el conjunto             
                    todosSuBconjuntosAFD.add(conj);
                    estadosAFD.add(String.valueOf(nombreestadoAFD));
                    nombreestadoAFD++;
            }  
   }

//crear tabla para el afnd
    public void tablaAFND(){
            int cont=1;
                System.out.println("alf"+alfabetoAFD.size());
                System.out.println("est"+estadosAFD.size());
        tablaAFD=new String[estadosAFD.size()][alfabetoAFD.size()];
        //para ubicar en la fila
         for(int x=0;x<estadosAFD.size();x++){
           for(int y=0;y<alfabetoAFD.size();y++){



                     for(int z=0;z<todosSuBconjuntosAFD.size();z++){
                         if(todosSuBconjuntosAFD_Repetidos.get(cont).equals(todosSuBconjuntosAFD.get(z))){
                            tablaAFD[x][y]=estadosAFD.get(z);
                             System.out.println("alf"+alfabetoAFD.size());
                            break;
                         }
                     }
                     cont++;

       }
       }





    }
    public ArrayList<String> nodosFinales(){
        nodoFinalesAFD=new ArrayList<String>();
         for(int x=0;x<todosSuBconjuntosAFD.size();x++){
              for(int y=0;y<nodosFinales.size();y++){
                  if(todosSuBconjuntosAFD.get(x).contains(nodosFinales.get(y))){
                      System.out.println("SIII");
                 if(!nodoFinalesAFD.contains(estadosAFD.get(x))){
                          nodoFinalesAFD.add(estadosAFD.get(x));
                                  System.out.println("SIII"+nodoFinalesAFD.size());
                    }
                    
                  }
                             
             }
         }
        return nodoFinalesAFD;
    }


}



